#pragma once

#include "spdlog/common.h"
#include "spdlog/logger.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"

class Logger {
private:
    std::shared_ptr<spdlog::logger> _log;
    Logger(const std::string &tag) {
        std::vector<spdlog::sink_ptr> sinks;
        sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
        sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(LOG_FILE_NAME, 1024 * 1024 * 100, 2));
        _log = std::make_shared<spdlog::logger>(tag, sinks.begin(), sinks.end());
        _log->flush_on(spdlog::level::info);
    };

    static inline std::shared_ptr<Logger> _logger = nullptr;

public:
    static Logger &get(const std::string &tag) {
        if (!_logger) {
            _logger.reset(new Logger(tag));
        }
        return *_logger;
    }

    template <typename... Args>
    void warn(spdlog::format_string_t<Args...> fmt, Args &&... args) { _log->warn(std::forward<spdlog::format_string_t<Args...>>(fmt), std::forward<Args>(args)...); }

    template <typename... Args>
    void info(spdlog::format_string_t<Args...> fmt, Args &&... args) { _log->info(std::forward<spdlog::format_string_t<Args...>>(fmt), std::forward<Args>(args)...); }

    template <typename... Args>
    void error(spdlog::format_string_t<Args...> fmt, Args &&... args) { _log->error(std::forward<spdlog::format_string_t<Args...>>(fmt), std::forward<Args>(args)...); }
};

#define info(...)  Logger::get("dev_dlt698").info(__VA_ARGS__)
#define warn(...)  Logger::get("dev_dlt698").warn(__VA_ARGS__)
#define error(...) Logger::get("dev_dlt698").error(__VA_ARGS__)